我在上传数据时使用PutObjectRequest类,其中的Key属性有严格限制,稍有不慎就会进坑,而创建一个假文件(48B或48K左右)
put.Key=文件夹名+"/"+ 文件名
文件名=本地文件名`</pre>
</div>
思路:遍历文件夹,读取所有文件夹、文件夹内文件,使用Task循环上传
<div>
<pre>`class UploadFilesInAll
{
/// <summary>
/// 访问密钥
/// </summary>
private static String accessKeyID = "访问密钥id";
/// <summary>
/// 密钥
/// </summary>
private static String secretKey = "私有访问密钥iD";
/// <summary>
/// 存储桶的名字
/// </summary>
private static String bucketName = "存储桶名字";
/// <summary>
/// 存放上传失败的文件的信息
/// </summary>
private static List<string> errorList = new List<string>();
/// <summary>
/// 存放获取到的路径
/// </summary>
static List<string> fileList = new List<string>();
/// <summary>
/// 成功个数
/// </summary>
static int successMum = 0;
/// <summary>
/// 失败个数
/// </summary>
static int failedNum = 0;
/// <summary>
/// file个数
/// </summary>
static int fileCount = 0;
/// <summary>
/// folder个数
/// </summary>
static int folderCount = 0;
/// <summary>
/// 批量上传文件的主体部分
/// </summary>
/// <returns></returns>
public static string UploadAllFiles()
{
#region 删除日志文件
string filePath = AppDomain.CurrentDomain.BaseDirectory + "Log.txt";
if (System.IO.File.Exists(filePath))
{
System.IO.File.Delete(filePath);
}
#endregion
string localPath = "";
AWSCredentials credentials;
credentials = new BasicAWSCredentials(accessKeyID.Trim(), secretKey.Trim());
AmazonS3Client s3Client = new AmazonS3Client(accessKeyID.Trim(), secretKey.Trim(), Amazon.RegionEndpoint.USEast1);
Console.WriteLine("验证成功");
Console.WriteLine("检查存储桶是否存在");
if (!Program.CheckBucketExists(s3Client, bucketName))
{
Console.WriteLine("正在创建数据桶........");
s3Client.PutBucket(bucketName);
Console.WriteLine("数据桶创建成功");
}
Dictionary<string, List<string>> fileList = UploadFilesInAll.GetAllFiles(@"E:\telerikFile");
WriteLog("共有" + fileCount + "个文件");
// 整理文件的路径,逐个上传
foreach (var item in fileList)
{
string key = item.Key.Substring(item.Key.LastIndexOf('\\'));
key = key.Substring(key.LastIndexOf('\\') + 1);
Console.WriteLine(key);
foreach (var item_ in item.Value)
{
localPath = item_;
string path = item_.Substring(item_.LastIndexOf('\\')+1);
Task.Run(()=> UploadFilesInAll.upload(s3Client, key+"/"+ path, item_));
}
}
try
{
Console.WriteLine("准备上传");
return "success";
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
return "failed";
}
}
/// <summary>
/// 文件上传部分
/// </summary>
/// <param name="s3Client">Amazon S3服务接口</param>
/// <param name="key">对象键(文件上传后存储的文件夹/文件)</param>
/// <param name="localFile">待上传数据存放路径</param>
private static void upload(AmazonS3Client s3Client,string key,string localFile)
{
Object objLock = new Object();
lock(objLock)
{
try
{
// 配置上传信息
string localPath = localFile;
PutObjectRequest obj = new PutObjectRequest();
var fileStream = new FileStream(localPath, FileMode.Open, FileAccess.Read);
obj.InputStream = fileStream;
obj.BucketName = bucketName;
obj.Key = key;
obj.CannedACL = S3CannedACL.PublicRead;
Console.WriteLine("正在上传" + localPath);
// 默认添加public权限
s3Client.PutObject(obj);
Console.WriteLine("上传成功第"+ (successMum+1) +"个文件" );
WriteLog("上传成功第" + (successMum+1) + "个文件" + localPath);
successMum++;
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
Console.WriteLine("上传失败"+ (failedNum+1) + "个文件" + localFile);
errorList.Add(localFile);
//WriteLog(" 失败" + filedNum++ + "个");
failedNum++;
WriteLog("上传失败" + localFile);
// return "failed";
}
}
if(successMum + 1== fileCount)
{
Console.WriteLine("文件已经全部下载,按任意键退出");
WriteLog("文件已经全部下载");
Console.ReadKey();
}
if(failedNum >=1)
{
WriteLog("当前失败率=" + failedNum * 1.00 / fileCount);
ShowError(s3Client);
}
else
{
//WriteLog("当前失败率=" + failedNum * 1.00 / fileCount);
}
}
/// <summary>
/// 再次上传主体部分
/// </summary>
/// <param name="s3Client">Amazon S3服务主体部分</param>
/// <param name="failedPath"></param>
private static void uploadAgain(AmazonS3Client s3Client,string failedPath)
{
Object objLock = new Object();
lock (objLock)
{
try
{
string key = failedPath.Substring(failedPath.LastIndexOf('\\'));
key = key.Substring(key.LastIndexOf('\\') + 1);
string localPath = failedPath;
PutObjectRequest obj = new PutObjectRequest();
var fileStream = new FileStream(localPath, FileMode.Open, FileAccess.Read);
obj.InputStream = fileStream;
obj.BucketName = bucketName;
obj.Key = key;
obj.CannedACL = S3CannedACL.PublicRead;
Console.WriteLine("正在上传" + localPath);
// 默认添加public权限
s3Client.PutObject(obj);
Console.WriteLine("上传成功" + localPath);
successMum++;
errorList.Remove(localPath);
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
Console.WriteLine("上传失败" + failedPath);
errorList.Add(failedPath);
failedNum++;
WriteLog(failedPath);
}
if ((failedNum * 1.00 / fileCount) > 0.00)
{
WriteLog("成功下载" + successMum + "个文件,失败" + failedNum + "个文件");
ShowError(s3Client);
}
}
}
/// <summary>
/// 整理错误信息,准备重新下载之前下载失败的文件
/// </summary>
/// <param name="s3Client">AmazonS3服务实例</param>
private static void ShowError(AmazonS3Client s3Client)
{
Object objLock = new Object();
lock (objLock)
{
int i = 0;
string path = "";
Console.WriteLine("当前失败率=" + failedNum * 1.00 / fileCount);
WriteLog("当前失败率=" + failedNum * 1.00 / fileCount);
try
{
successMum = 0;
failedNum = 0;
foreach (var item in errorList)
{
i++;
path = item;
Console.WriteLine(item);
Task.Run(() => uploadAgain(s3Client, item));
}
}
catch
{
WriteLog("第"+i+"个失败:" + path);
Console.WriteLine("执行错误");
}
}
}
/// <summary>
/// 获取所有文件的路径
/// </summary>
/// <param name="path"></param>
/// <returns></returns>
public static Dictionary<string, List<string>> GetAllFiles(string path)
{
Dictionary<string, List<string>> fileTree = new Dictionary<string, List<string>>();
List<string> list;
DirectoryInfo[] folder = new DirectoryInfo(@"E:\telerikFile").GetDirectories();
for (int i = 0; i < folder.Length; i++)
{
folderCount++;
list = list = new List<string>();
for (int j = 0; j < folder[i].GetFiles().Length; j++)
{
fileCount++;
list.Add(folder[i].GetFiles()[j].FullName.ToString());
}
fileTree.Add(folder[i].FullName, list);
// list.Clear();
}
WriteLog("共有"+ folderCount +"个文件夹,"+ fileCount+"个文件");
return fileTree;
//foreach (var dicName in list)
//{
// Console.WriteLine(dicName);
// Console.WriteLine(dicName.Count());
//}
}
/// <summary>
/// 获取指定的根目录的所有子目录名称
/// </summary>
/// <param name="path">指定的根目录</param>
/// <returns>子目录名称集合</returns>
public static List<string> getPath(string path)
{
DirectoryInfo dir = new DirectoryInfo(path);
FileInfo[] fil = dir.GetFiles();
DirectoryInfo[] dii = dir.GetDirectories();
foreach (FileInfo f in fil)
{
fileList.Add(f.FullName);//添加文件的路径到列表
}
//获取子文件夹内的文件列表,递归遍历
foreach (DirectoryInfo d in dii)
{
getPath(d.FullName);
fileList.Add(d.FullName);//添加文件夹的路径到列表
}
return fileList;
}
/// <summary>
/// 写入文件,做记录测试
/// </summary>
/// <param name="str"></param>
private static void WriteLog(string str)
{
Task.Run(() =>
{
try
{
string filePath = AppDomain.CurrentDomain.BaseDirectory + "Log.txt";
StreamWriter sw = null;
if (!System.IO.File.Exists(filePath))
{
sw = System.IO.File.CreateText(filePath);
}
else
{
sw = System.IO.File.AppendText(filePath);
}
sw.Write(str + Environment.NewLine);//+ DateTime.Now.ToString()
sw.Close();
}
catch (Exception ex)
{
ex.ToString();
}
});
}
}